page.tsx 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. "use client";
  2. import {
  3. getCommissionApi,
  4. getRegisterCountApi,
  5. getTotalCountApi,
  6. getWithdrawalApi,
  7. } from "@/api/summary";
  8. import { CommissionModel } from "@/app/[locale]/affiliate/component/TabsCom";
  9. import Table, { TableHeaderItem } from "@/components/Table";
  10. import TipsModal, { ModalProps } from "@/components/TipsModal";
  11. import { usePathname } from "@/i18n/routing";
  12. import { useUserInfoStore } from "@/stores/useUserInfoStore";
  13. import { server } from "@/utils/client";
  14. import { getToken } from "@/utils/Cookies";
  15. import { copyText, flatPoint } from "@/utils/methods";
  16. import { useRequest } from "ahooks";
  17. import { Mask, Toast } from "antd-mobile";
  18. import { useTranslations } from "next-intl";
  19. import Image from "next/image";
  20. import { FC, useEffect, useRef, useState } from "react";
  21. import "./page.scss";
  22. interface Props {}
  23. const RulesClient = () => {
  24. const t = useTranslations("cashback");
  25. const [rules, setRules] = useState<any>([]);
  26. const [visible, setVisible] = useState(false);
  27. const columns: TableHeaderItem[] = [
  28. {
  29. title: <div className={"text-center text-[#98a7b5]"}>Nivel Agente</div>,
  30. dataIndex: "agent_level",
  31. align: "center",
  32. render: (item: any) => (
  33. <div className={"text-[0.12rem] text-[#98a7b5]"}>{item?.agent_level}</div>
  34. ),
  35. },
  36. {
  37. title: <div className={"text-center text-[#98a7b5]"}>Apostas Validas</div>,
  38. dataIndex: "bet",
  39. align: "center",
  40. render: (item: any) => (
  41. <div className={"text-[0.12rem] text-[#98a7b5]"}>{item?.bet / 10000} Dez mil+</div>
  42. ),
  43. },
  44. {
  45. title: <div className={"text-center text-[#98a7b5]"}>Comissão</div>,
  46. dataIndex: "ratio",
  47. render: (item: any) => (
  48. <div className={"text-center text-[0.12rem] text-[#db922b]"}>
  49. {flatPoint(item?.ratio / 100)}
  50. <span className={"text-[#98a7b5]"}>%</span>
  51. </div>
  52. ),
  53. },
  54. ];
  55. const loadMore = async () => {
  56. return Promise.resolve();
  57. };
  58. const getCashBackApi = async () => {
  59. return server
  60. .request<any>({
  61. url: "/v1/api/user/get_user_config_agent_info",
  62. method: "post",
  63. })
  64. .then((res) => {
  65. return {
  66. rules: res.data || [],
  67. };
  68. })
  69. .catch((error) => {
  70. return {
  71. rules: [],
  72. last_period: { end_time: 0, start_time: 0 },
  73. next_period: {
  74. end_time: 0,
  75. start_time: 0,
  76. },
  77. amount: 0,
  78. bet: 0,
  79. status: "expired",
  80. };
  81. });
  82. };
  83. useEffect(() => {
  84. getCashBackApi().then((res) => {
  85. setRules(res.rules);
  86. });
  87. }, []);
  88. return (
  89. <div className={"text-[0.12rem]"}>
  90. <div className={"bg-[#0e1319] p-[0.0694rem]"}>
  91. <Table
  92. columns={columns}
  93. headerClassName={" bg-[#151d28] "}
  94. bodyClassName={"odd:bg-[#0e1319] even:bg-[#151d28]"}
  95. dataSource={rules || []}
  96. loadMore={loadMore}
  97. hasMore={false}
  98. isLoadMore={false}
  99. isBackground={false}
  100. />
  101. </div>
  102. <div className={"mt-[0.1389rem] flex items-center text-[#98a7b5]"}>
  103. <p
  104. className={"mr-[0.1389rem] h-[0.0694rem] w-[0.0694rem] rounded bg-[#98a7b5]"}
  105. ></p>{" "}
  106. A apostas válidas depende dos diferentes jogos:
  107. </div>
  108. <div className={"mt-[0.1389rem] flex bg-[#25262b] p-[0.1389rem] text-[#98a7b5]"}>
  109. <span className={"iconfont icon-tishi text-[0.10rem]"}></span>
  110. <div className={"ml-[0.0694rem]"}>
  111. Os tipos de crash e os jogos virtuais não serão considerados apostas válidas{" "}
  112. </div>
  113. </div>
  114. <div className={"mt-[0.1389rem] bg-[#25262b] p-[0.1389rem] text-[#98a7b5]"}>
  115. <div>
  116. <span className={"text-[0.22rem] text-[#fff]"}>100%</span>
  117. <span> De aposta </span>
  118. </div>
  119. <div>
  120. <span className={"text-[#575f6a]"}>Jogos : </span>
  121. <span> Live Casino, 3rd Party</span>
  122. </div>
  123. </div>
  124. <div className={"mt-[0.1389rem] bg-[#25262b] p-[20px] text-[#98a7b5]"}>
  125. <div>
  126. <span className={"text-[0.22rem] text-[#fff]"}>100%</span>
  127. <span> De aposta </span>
  128. </div>
  129. <div>
  130. <span className={"text-[#575f6a]"}>Jogos : </span>
  131. <span>Os outros jogos originais</span>
  132. </div>
  133. </div>
  134. <div
  135. onClick={() => setVisible(true)}
  136. className={
  137. "mt-[0.1389rem] flex justify-between bg-[#25262b] p-[0.1042rem] text-[#98a7b5]"
  138. }
  139. >
  140. Regras de cálculo de comissão
  141. <span className={"iconfont icon-xiangyou2"}></span>
  142. </div>
  143. <ul className={"ml-[0.1389rem] mt-[0.1389rem] list-disc text-[#98a7b5]"}>
  144. <li className={"mt-[0.0694rem]"}>
  145. As comissões podem ser retiradas em nossa carteira bcwin do painel a qualquer
  146. momento.
  147. </li>
  148. <li className={"mt-[0.0694rem]"}>O sistema calcula a comissão a cada 3 minutos.</li>
  149. <li className={"mt-[0.0694rem]"}>Comissão máxima diária : 10000 BRL</li>
  150. <li className={"mt-[0.0694rem]"}>
  151. A comissão não será creditada para o mesmo IP ou dispositivo, e a inflação
  152. intencional do volume de negócios não será creditada para a comissão.{" "}
  153. </li>
  154. </ul>
  155. <CommissionModel visible={visible} setVisible={setVisible} />
  156. </div>
  157. );
  158. };
  159. const App: FC<Props> = (props) => {
  160. const t = useTranslations("SummaryPage");
  161. const sliderRef = useRef<HTMLDivElement>(null);
  162. const pathname = usePathname();
  163. const [num, setNum] = useState(100);
  164. const [money, setMoney] = useState("5000");
  165. const [visible, setVisible] = useState(false);
  166. const [BASE_URL, setBaseUrl] = useState("");
  167. const todayModalRef = useRef<ModalProps>(null);
  168. const totalModalRef = useRef<ModalProps>(null);
  169. const { userInfo } = useUserInfoStore();
  170. const token = getToken();
  171. // 生成分享链接
  172. // const BASE_URL = window.location.href.replace(pathname, "");
  173. const shareUrl = `${BASE_URL}/${userInfo ? userInfo.referrer_code : "xxxxxx"}`;
  174. const url = encodeURIComponent(`${shareUrl}`);
  175. const SHARE_SOURCE = [
  176. {
  177. icon: "/summary/Facebook.png",
  178. label: "Facebook",
  179. shareUrl: `https://www.facebook.com/sharer/sharer.php?u=${url}`,
  180. },
  181. {
  182. icon: "/summary/WhatsApp.png",
  183. label: "WhatsApp",
  184. shareUrl: `https://api.whatsapp.com/send?text=${url}`,
  185. },
  186. {
  187. icon: "/summary/Telegram.png",
  188. label: "Telegram",
  189. shareUrl: `https://t.me/share/url?url=${url}`,
  190. },
  191. {
  192. icon: "/summary/Twitter.png",
  193. label: "Twitter",
  194. shareUrl: `https://twitter.com/intent/tweet?text=${url}`,
  195. },
  196. {
  197. icon: "/summary/Email.png",
  198. label: "Email",
  199. shareUrl: `mailto: ?&subject=&cc=&bcc=&body=${url}`,
  200. },
  201. ];
  202. // 轮询时间
  203. const TIME = 180000;
  204. const getUserMoneyHandler = () => {
  205. if (token) {
  206. return getRegisterCountApi().then((res) => {
  207. if (res.code === 200) return res.data;
  208. });
  209. }
  210. return Promise.resolve({
  211. commissar: 0,
  212. effective_amount: 0,
  213. recharge_user_count: 0,
  214. reg_count: 0,
  215. });
  216. };
  217. const { data: todayData } = useRequest(getUserMoneyHandler, {
  218. pollingInterval: TIME,
  219. pollingWhenHidden: true,
  220. pollingErrorRetryCount: 3,
  221. staleTime: 5000,
  222. refreshDeps: [token],
  223. });
  224. const getTotalCount = () => {
  225. if (token) {
  226. return getTotalCountApi().then((res) => {
  227. if (res.code === 200) return res.data;
  228. });
  229. }
  230. return Promise.resolve({
  231. commissar: 0,
  232. effective_amount: 0,
  233. recharge_user_count: 0,
  234. reg_count: 0,
  235. });
  236. };
  237. const { data: totalData } = useRequest(getTotalCount, {
  238. pollingInterval: TIME,
  239. pollingWhenHidden: true,
  240. pollingErrorRetryCount: 3,
  241. staleTime: 5000,
  242. });
  243. const getCommission = () => {
  244. if (token) {
  245. return getCommissionApi().then((res) => {
  246. if (res.code === 200) return res.data;
  247. });
  248. }
  249. return Promise.resolve({
  250. commissar: 0,
  251. level: 0,
  252. withdrawal_commissions: 0,
  253. enable_receive: false,
  254. min_value: 0,
  255. max_value: 0,
  256. });
  257. };
  258. const { data: commissionData, run: commissionRun } = useRequest(getCommission, {
  259. pollingInterval: TIME,
  260. pollingWhenHidden: true,
  261. pollingErrorRetryCount: 3,
  262. staleTime: 5000,
  263. });
  264. const handleSlide: any = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
  265. if (sliderRef.current) {
  266. const startX = sliderRef.current.getBoundingClientRect().x;
  267. const x = e.clientX - startX;
  268. const xRem = x / (144 * 0.6);
  269. const intNum = Math.round(10000 * xRem) - Math.round((10000 * xRem) % 10);
  270. setNum(intNum);
  271. const m = intNum * 50;
  272. let r = "";
  273. const arr = m.toString().split("");
  274. arr.forEach((item, i) => {
  275. if (i !== arr.length - 1 && (arr.length - i - 1) % 3 === 0) {
  276. r += item + ",";
  277. } else {
  278. r += item;
  279. }
  280. });
  281. setMoney(r);
  282. const scale = (Math.round(xRem * 10000) / 100.0).toFixed(2) + "%";
  283. sliderRef.current.style.width = scale;
  284. }
  285. };
  286. const copy = (text: string) => {
  287. copyText(text);
  288. Toast.show({ icon: "success", content: t("copySuc"), maskClickable: false });
  289. };
  290. const withdrawalHandler = async () => {
  291. if (commissionData === undefined) return;
  292. if (!commissionData.enable_receive) {
  293. Toast.show(t("receive"));
  294. return;
  295. }
  296. const commissar = commissionData.commissar ?? 0; // 使用空值合并运算符处理可能的 undefined
  297. const minValue = Math.min(commissionData.min_value, 10);
  298. if (commissar > minValue) {
  299. const available = Math.min(commissionData.max_value, commissar);
  300. getWithdrawalApi({ amount: available }).then((res) => {
  301. if (res.code === 200) {
  302. setTimeout(commissionRun, 200);
  303. }
  304. });
  305. return;
  306. } else {
  307. Toast.show(t("receive"));
  308. }
  309. };
  310. useEffect(() => {
  311. setBaseUrl(window.location.href.replace(pathname, ""));
  312. }, []);
  313. return (
  314. <div className="content">
  315. <div className="summary referral-router-view">
  316. <div className="content" style={{ marginTop: 0 }}>
  317. <div className="title">
  318. <div>
  319. {t("Hoje")}
  320. <span
  321. className="iconfont icon-bangzhu"
  322. onClick={() => todayModalRef.current?.onOpen()}
  323. />
  324. </div>
  325. </div>
  326. <div className="cardMian">
  327. <ul className="statistics-card">
  328. <li>
  329. <p className="num">{flatPoint(todayData?.reg_count ?? 0)}</p>
  330. <p> {t("Inscrições")} </p>
  331. </li>
  332. <li>
  333. <p className="num">
  334. {flatPoint(todayData?.recharge_user_count ?? 0)}
  335. </p>
  336. <p> {t("Novos")} </p>
  337. </li>
  338. <li>
  339. <p className="num">
  340. <span className={"mr-[5px]"}>{t("R$")}</span>
  341. {flatPoint(todayData?.effective_amount ?? 0)}
  342. </p>
  343. <p> {t("Aposta")} </p>
  344. </li>
  345. <li>
  346. <p className="num">
  347. <span className={"mr-[5px]"}>{t("R$")}</span>
  348. {flatPoint(todayData?.commissar ?? 0)}
  349. </p>
  350. <p> {t("Comissão")} </p>
  351. </li>
  352. </ul>
  353. </div>
  354. </div>
  355. <div className="content">
  356. <div className="title">
  357. <div>
  358. {t("Total")}
  359. <span
  360. className="iconfont icon-bangzhu"
  361. onClick={() => totalModalRef.current?.onOpen()}
  362. />
  363. </div>
  364. </div>
  365. <div className="cardMian">
  366. <ul className="statistics-card">
  367. <li>
  368. <p className="num">{flatPoint(totalData?.reg_count ?? 0)}</p>
  369. <p> {t("Inscrições")} </p>
  370. </li>
  371. <li>
  372. <p className="num">
  373. {flatPoint(totalData?.recharge_user_count ?? 0)}
  374. </p>
  375. <p> {t("Jogadores")} </p>
  376. </li>
  377. <li>
  378. <p className="num">
  379. <span className={"mr-[5px]"}>{t("R$")}</span>
  380. {flatPoint(totalData?.effective_amount ?? 0)}
  381. </p>
  382. <p> {t("ApostaTotal")} </p>
  383. </li>
  384. <li>
  385. <p className="num">
  386. <span className={"mr-[5px]"}>{t("R$")}</span>
  387. {flatPoint(totalData?.commissar ?? 0)}
  388. </p>
  389. <p>RS {t("Comissão")} </p>
  390. </li>
  391. </ul>
  392. </div>
  393. </div>
  394. <div className="content">
  395. <div className="title">
  396. <div>
  397. {t("Comissão")}
  398. <span
  399. className="iconfont icon-bangzhu"
  400. onClick={() => setVisible(true)}
  401. />
  402. </div>
  403. </div>
  404. <div className="cardMian">
  405. <div className="vip">
  406. <div className="level">
  407. {/*<span className="iconfont icon-vip"></span>*/}
  408. <Image
  409. src={"/summary/level.png"}
  410. alt={"level"}
  411. height={120}
  412. width={120}
  413. />
  414. <span className="levelNum">{commissionData?.level}</span>
  415. </div>
  416. <div>
  417. {t("Nível")}
  418. <span
  419. className="iconfont icon-tishi"
  420. onClick={() => setVisible(true)}
  421. ></span>
  422. </div>
  423. </div>
  424. <div>
  425. <ul className="commission">
  426. <li>
  427. <p className="num">
  428. <span>{t("R$")}</span>
  429. <span className="cash">
  430. {flatPoint(commissionData?.withdrawal_commissions ?? 0)}
  431. </span>
  432. </p>
  433. <p> {t("TotalPago")} </p>
  434. </li>
  435. <li>
  436. <p className="num">
  437. <span>{t("R$")}</span>
  438. <span className="cash">
  439. {flatPoint(commissionData?.commissar ?? 0)}
  440. </span>
  441. </p>
  442. <p> {t("Não")} </p>
  443. </li>
  444. </ul>
  445. <div className="wallet">
  446. <div className="btn" onClick={withdrawalHandler}>
  447. {t("TRANSFERIR")}
  448. </div>
  449. <div className="tip">
  450. <span className="iconfont icon-tishi1"></span>
  451. {t("Valor")}
  452. </div>
  453. </div>
  454. </div>
  455. </div>
  456. </div>
  457. <div className="content shareMain">
  458. <div className="title">
  459. <div>{t("title1")}</div>
  460. </div>
  461. <div className="share">
  462. <ul className="sharePlatform">
  463. {SHARE_SOURCE.map((item, index) => {
  464. return (
  465. <a
  466. href={item.shareUrl}
  467. key={index}
  468. target={"_blank"}
  469. className={"flex flex-col items-center"}
  470. >
  471. <Image
  472. src={item.icon}
  473. alt={"Mais"}
  474. width={70}
  475. height={70}
  476. />
  477. <p className={"mt-[0.0347rem] text-[12px] text-[#808080]"}>
  478. {item.label}
  479. </p>
  480. </a>
  481. );
  482. })}
  483. </ul>
  484. </div>
  485. <div className="shareLink">
  486. <div className="">{t("content1")}</div>
  487. <div className="copyUrl">
  488. <span className="url omitWrap">{shareUrl}</span>
  489. <span id="copy" onClick={() => copy(shareUrl)}>
  490. {t("Cópia")}
  491. </span>
  492. </div>
  493. </div>
  494. </div>
  495. <div className="content">
  496. <div className="title">
  497. <div> {t("title2")}</div>
  498. </div>
  499. <div>
  500. <div className="tel-box">
  501. <a href="" className="telicon">
  502. <Image
  503. src="/summary/telegram-nobg.png"
  504. height={100}
  505. width={100}
  506. alt="telegram"
  507. />
  508. </a>
  509. <div className="hintTitle3">{t("content2-1")}</div>
  510. </div>
  511. <div className="hintTitle2">
  512. <i className="iconfont icon-tishi"></i>
  513. {t("content2-2")}
  514. <a
  515. href="https://t.me/jogobcwinOfficialChanel"
  516. target={"_blank"}
  517. style={{
  518. borderBottom: "1px solid rgb(109, 155, 195)",
  519. color: "#0000EE",
  520. }}
  521. >
  522. {t("business")}
  523. </a>
  524. </div>
  525. </div>
  526. </div>
  527. <div className="content">
  528. <div className="title">
  529. <div>
  530. {t("title3")}
  531. <span
  532. className="iconfont icon-bangzhu"
  533. onClick={() => setVisible(true)}
  534. ></span>
  535. </div>
  536. </div>
  537. <div className="hint">
  538. <div className="hintTitle">{t("content3")}</div>
  539. <div className="imgContent">
  540. <Image width={100} height={100} src="/summary/money.png" alt="" />
  541. <div>
  542. {t("number")}
  543. {num}
  544. <br />
  545. {t("Comissão")} &gt; {t("R$")} {money} {t("money")}
  546. </div>
  547. <div
  548. className="slider van-slider"
  549. style={{ height: "0.02rem" }}
  550. onClick={handleSlide}
  551. >
  552. <div
  553. className="van-slider__bar"
  554. style={{ width: "0.900901%", background: "rgb(0, 157, 128)" }}
  555. ref={sliderRef}
  556. >
  557. <div role="slider" className="van-slider__button-wrapper">
  558. <div className="img"></div>
  559. </div>
  560. </div>
  561. </div>
  562. </div>
  563. <div className="relationSchema">
  564. <div className="groupTitle">{t("title4")}</div>
  565. <img src="/summary/group_br.png" alt="" className="groupImg" />
  566. <ul className="rules">
  567. <li>
  568. {t("content4-1")}
  569. <span style={{ color: "red" }}>{t("red")}</span>.
  570. </li>
  571. <li>{t("content4-2")}</li>
  572. </ul>
  573. </div>
  574. </div>
  575. </div>
  576. <div className="content"></div>
  577. </div>
  578. <TipsModal title={t("modalTitle")} ref={todayModalRef}>
  579. <ul className={"list-decimal break-all p-[0.1389rem] pt-0 font-bold"}>
  580. <li>{t("todayDesc1")}</li>
  581. <li>{t("todayDesc2")}</li>
  582. <li>{t("todayDesc3")}</li>
  583. </ul>
  584. <p className={"text-[gray]"}>{t("modalTips")}</p>
  585. </TipsModal>
  586. <TipsModal title={t("modalTitle")} ref={totalModalRef}>
  587. <ul className={"list-decimal break-all p-[0.1389rem] pt-0 font-bold"}>
  588. <li>{t("totalDesc1")}</li>
  589. <li>{t("totalDesc2")}</li>
  590. <li>{t("totalDesc3")}</li>
  591. </ul>
  592. <p className={"text-[gray]"}>{t("modalTips")}</p>
  593. </TipsModal>
  594. <Mask visible={visible} getContainer={null}>
  595. <div className={"h-[100vh] w-[100%] overflow-scroll bg-[#1f2024]"}>
  596. <div
  597. className={
  598. "absolute top-0 flex items-center justify-between " +
  599. " h-[0.4167rem] w-[100%] border-[1px] bg-[#17181c] px-[0.1389rem]" +
  600. " z-10 border-[#666]"
  601. }
  602. >
  603. <p>Regras de recompensas por comissão</p>
  604. <i className={"iconfont icon-guanbi"} onClick={() => setVisible(false)}></i>
  605. </div>
  606. <div className={"mt-[0.4167rem] px-[0.1389rem] pt-[0.1389rem]"}>
  607. <RulesClient />
  608. </div>
  609. </div>
  610. </Mask>
  611. </div>
  612. );
  613. };
  614. export default App;